package com.jsj.bs.controller;

import com.jsj.bs.pojo.Result;
import com.jsj.bs.pojo.TbUser;
import com.jsj.bs.service.TbUserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.SessionStatus;

import javax.servlet.http.HttpSession;

/**
 * (TbUser)表控制层
 *
 * @author King_long
 * @since 2019-12-04 11:04:55
 */
@Controller
@RequestMapping("/tbUser")
public class TbUserController {
    /**
     * log4j2 日志管理
     */
    private static final Logger LOGGER = LogManager.getLogger(TbUserController.class);
    /**
     * 返回的结果集 自定义
     */
    private static final Result resultMsg = new Result();
    /**
     * 服务对象
     */
    @Autowired
    private TbUserService userService;


    /**
     * 用户管理 用户注册
     *
     * @param tbUser  用户实体对象
     * @param session jsp的内置对象 服务端存储数据的对象  30分钟内有效
     * @param model   存储数据的容器
     * @return 指定页面
     */
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public String userRegister(TbUser tbUser, HttpSession session, Model model) {
        TbUser user = userService.queryById(tbUser.getUserAccount());
        if (user == null) {
            //添加用户角色
            tbUser.setRoleId(3);
            //获取账户密码
            String password = tbUser.getUserPassword();
            LOGGER.info(tbUser.getUserAccount()+"====加密前后的账号==="+password);
            //使用MD5加密 第一个参数--加密的字符串  第二个参数---盐值  第三个参数---加盐次数 即散列次数
            password = new Md5Hash(password, tbUser.getUserAccount(), 1024).toString();
            //将加密后的密码添加到TbAdmin实体对象中
            tbUser.setUserPassword(password);
            LOGGER.info(tbUser.getUserAccount()+"====加密后的账号==="+password);
            //用户不存在，可以注册
            TbUser insert = userService.insert(tbUser);
            //返回 1 成功  0 失败
            session.setAttribute("status", 1);
            session.setAttribute("msg", "注册成功,请登录");
            return "login-user";
        }
        session.setAttribute("status", 0);
        session.setAttribute("msg", "账户已存在，请重新注册");
        return "redirect:/register";
    }

    /**
     * 验证码验证
     *
     * @param model
     * @param message
     * @return 指定页面
     */
    @RequestMapping("/loginView")
    public String loginView(Model model, String message) {
        model.addAttribute("msg", "登陆失败，验证码错误");
        LOGGER.info("验证码错误");
        return "login-user";
    }

    /**
     * 用户管理 用户登陆
     *
     * @param userAccount  用户账号
     * @param userPassword 用户密码
     * @return 指定页面
     */
    @RequestMapping("/login-user")
    public String loginUser(@RequestParam("userAccount") String userAccount,
                            @RequestParam("userPassword") String userPassword,
                            HttpSession session,
                            Model model) {

        LOGGER.error(userAccount + "===============" + userPassword);
        //3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(userAccount, userPassword);

        try {
            //4、登录，即身份验证
            subject.login(token);
            if (subject.isAuthenticated()) {
                Boolean status = userService.queryStatus(userAccount);
                if (!status && subject.hasRole("user")) {
                    session.setAttribute("account", userAccount);
                    session.setAttribute("hasRole", "hasUser");
                    return "userpage";
                }
                session.setAttribute("msg", "当前账户异常，请联系管理员" + status);
                return "redirect:/error";
            }
        } catch (AuthenticationException e) {
            //5、身份验证失败
            e.printStackTrace();
        }
        session.setAttribute("msg", "账户或密码错误");
        return "redirect:/error";
    }

    /**
     * 用户管理 修改密码
     *
     * @param tbUser  用户实体对象
     * @param session jsp的内置对象 服务端存储数据的对象  30分钟内有效
     * @param status
     * @return
     */
    @RequestMapping(value = "/upTbUser", method = RequestMethod.POST)
    public String upTbUser(TbUser tbUser, HttpSession session, SessionStatus status) {

        LOGGER.info(tbUser + "=======================controller  up===========");
        //获取账户密码
        String password = tbUser.getUserPassword();
        //使用MD5加密 第一个参数--加密的字符串  第二个参数---盐值  第三个参数---加盐次数 即散列次数
        password = new Md5Hash(password, tbUser.getUserAccount(), 1024).toString();
        //将加密后的密码添加到TbAdmin实体对象中
        tbUser.setUserPassword(password);
        //更新密码操作
        TbUser user = userService.update(tbUser);
        //判断是否更新成功
        if (user != null) {
            System.out.println("=进入清除session=");
            session.removeAttribute("account");
            status.setComplete();
            System.out.println("==清理完成==");
            session.setAttribute("msg", "修改完成，请重新登陆");
            session.setAttribute("status", 1);
            return "redirect:/login-user";
        }
        session.setAttribute("msg", "修改失败，请联系管理员");
        return "redirect:/error";
    }

    /**
     * 管理员管理 查询所有用户信息
     *
     * @param page     页码
     * @param pageSize 页面大小
     * @param tbUser   用户实体对象
     * @param model    存储数据的容器
     * @return 指定页面
     */
    @RequestMapping(value = "/searchUser", method = RequestMethod.GET)
    public String search(@RequestParam(value = "page", defaultValue = "1") Integer page,
                         @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
                         TbUser tbUser, Model model) {
        //将获取的数据存到model，以便jsp页面获取
        model.addAttribute("userInfos", userService.queryAll(page, pageSize, tbUser));
        return "user-manager";
    }

    /**
     * 管理员管理 模糊查询
     *
     * @param fuzzy 查询信息
     * @param model 存储数据的容器
     * @return 指定页面
     */
    @RequestMapping(value = "/fuzzy", method = RequestMethod.POST)
    public String searchFuzzy(String fuzzy, Model model) {
        model.addAttribute("userInfos", userService.searchFuzzy(1, 5, fuzzy));
        return "user-manager";
    }

    /**
     * 管理员管理 更新用户状态
     *
     * @param tbUser 用户实体对象
     * @return 结果集（响应信息和相应标识）
     */
    @RequestMapping(value = "/updateStatus", method = RequestMethod.POST)
    @ResponseBody
    public Result updateStatus(TbUser tbUser) {
        LOGGER.info("=======/tbUser/updateStatus======" + tbUser.getUserId());
        Boolean result = userService.updateOk(tbUser);
        if (result) {
            resultMsg.setFlag(true);
            resultMsg.setMsg("操作成功");
        } else {
            resultMsg.setFlag(false);
            resultMsg.setMsg("操作失败");
        }
        return resultMsg;
    }

    /**
     * 管理员管理 添加用户
     *
     * @param tbUser 用户实体对象
     * @param model  存储数据的容器
     * @return 指定页面
     */
    @RequestMapping(value = "addUser", method = RequestMethod.POST)
    public String addUser(TbUser tbUser, Model model) {
        TbUser user = userService.queryById(tbUser.getUserAccount());
        if (user == null) {
            //添加用户角色
            tbUser.setRoleId(3);
            //获取账户密码
            String password = tbUser.getUserPassword();
            //使用MD5加密 第一个参数--加密的字符串  第二个参数---盐值  第三个参数---加盐次数 即散列次数
            password = new Md5Hash(password, tbUser.getUserAccount(), 1024).toString();
            //将加密后的密码添加到TbAdmin实体对象中
            tbUser.setUserPassword(password);
            //用户不存在，可以添加
            TbUser insert = userService.insert(tbUser);
            //返回 1 成功  0 失败
            LOGGER.info("=======添加用户的信息====" + insert);
            if (insert != null) {
                model.addAttribute("StatusMsg", 7);
                return "updateresult";
            }
        }
        model.addAttribute("StatusMsg", 8);
        return "updateresult";
    }
}